// 自行车外贸站 - 三数据库统一配置
import pg from 'pg';
import redis from 'redis';
import { MongoClient } from 'mongodb';
import config from '../../config/config.js';

const { Pool } = pg;

// ==================== PostgreSQL配置 ====================
// 核心业务数据库：用户、产品、订单、财务
// 基于2核8G内存优化配置
const postgresPool = new Pool({
  host: config.database.postgresql.host,
  port: config.database.postgresql.port,
  database: config.database.postgresql.name,
  user: config.database.postgresql.user,
  password: config.database.postgresql.password,
  
  // 2核8G内存优化配置
  max: config.database.postgresql.maxConnections || 30,           // 最大连接数（适合2核8G）
  min: config.database.postgresql.minConnections || 5,           // 最小连接数
  idleTimeoutMillis: config.database.postgresql.idleTimeout || 60000, // 空闲超时60秒
  connectionTimeoutMillis: config.database.postgresql.connectionTimeout || 10000, // 连接超时10秒
  
  // 内存优化参数
  maxUses: config.database.postgresql.maxUses || 5000,           // 连接最大使用次数
  allowExitOnIdle: config.database.postgresql.allowExitOnIdle !== false,
  
  // 连接重试配置（5秒间隔）
  retry: {
    max: 3,
    delay: 5000
  }
});

// ==================== Redis配置 ====================
// 高性能缓存：会话、热门数据、实时统计
// 基于2核8G内存优化配置
const redisClient = redis.createClient({
  socket: {
    host: config.database.redis.host,
    port: config.database.redis.port,
    
    // 连接重试配置（5秒间隔）
    reconnectStrategy: (retries) => {
      if (retries > 3) {
        console.warn('Redis连接重试次数过多，停止重试');
        return new Error('Redis连接失败');
      }
      console.log(`Redis连接重试第${retries}次，${5000}ms后重试`);
      return 5000; // 5秒重试间隔
    }
  },
  password: config.database.redis.password,
  database: config.database.redis.db,
  
  // 内存优化参数
  pingInterval: 30000,           // 30秒发送一次ping保持连接
  maxRetriesPerRequest: 3,       // 每个请求最大重试次数
  
  // 连接池配置（适合2核8G）
  poolSize: 20,                  // 连接池大小
  connectTimeout: 10000,         // 连接超时10秒
  commandTimeout: 15000          // 命令超时15秒
});

// ==================== MongoDB配置 ====================
// 文档存储：社区内容、用户行为、个性化数据
let mongoClient = null;
let mongoDb = null;

async function connectMongoDB() {
  try {
    mongoClient = new MongoClient(config.database.mongodb.uri, {
      maxPoolSize: config.database.mongodb.poolSize || 10,
      serverSelectionTimeoutMS: 5000,
      socketTimeoutMS: 45000
    });
    
    await mongoClient.connect();
    mongoDb = mongoClient.db(config.database.mongodb.db);
    console.log('✅ MongoDB连接成功');
    
    // 创建索引
    await createMongoIndexes();
    
  } catch (error) {
    console.error('❌ MongoDB连接失败:', error.message);
    throw error;
  }
}

// MongoDB索引创建
async function createMongoIndexes() {
  try {
    // 产品评价索引
    await mongoDb.collection('product_reviews').createIndex({ 
      product_id: 1, 
      created_at: -1 
    });
    
    // 社区讨论索引
    await mongoDb.collection('community_posts').createIndex({ 
      category: 1, 
      created_at: -1 
    });
    
    // 用户行为索引
    await mongoDb.collection('user_behavior').createIndex({ 
      user_id: 1, 
      action_type: 1, 
      timestamp: -1 
    });
    
    console.log('✅ MongoDB索引创建完成');
  } catch (error) {
    console.warn('⚠️ MongoDB索引创建失败:', error.message);
  }
}

// ==================== 连接测试函数 ====================

// PostgreSQL连接测试
async function testPostgresConnection(maxRetries = 3, retryDelay = 5000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const result = await postgresPool.query('SELECT NOW() as current_time');
      console.log('✅ PostgreSQL连接测试成功:', result.rows[0].current_time);
      return true;
    } catch (error) {
      if (attempt < maxRetries) {
        console.warn(`⚠️ PostgreSQL连接测试失败 (尝试 ${attempt}/${maxRetries}):`, error.message);
        console.log(`⏳ ${retryDelay/1000}秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        console.warn('⚠️ PostgreSQL连接测试最终失败:', error.message);
        return false;
      }
    }
  }
}

// Redis连接测试
async function testRedisConnection(maxRetries = 3, retryDelay = 5000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      if (!redisClient.isOpen) {
        await redisClient.connect();
      }
      const pong = await redisClient.ping();
      console.log('✅ Redis连接测试成功:', pong);
      return true;
    } catch (error) {
      if (attempt < maxRetries) {
        console.warn(`⚠️ Redis连接测试失败 (尝试 ${attempt}/${maxRetries}):`, error.message);
        console.log(`⏳ ${retryDelay/1000}秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        console.warn('⚠️ Redis连接测试最终失败:', error.message);
        return false;
      }
    }
  }
}

// MongoDB连接测试
async function testMongoConnection(maxRetries = 3, retryDelay = 5000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      if (!mongoClient) {
        await connectMongoDB();
      }
      await mongoDb.command({ ping: 1 });
      console.log('✅ MongoDB连接测试成功');
      return true;
    } catch (error) {
      if (attempt < maxRetries) {
        console.warn(`⚠️ MongoDB连接测试失败 (尝试 ${attempt}/${maxRetries}):`, error.message);
        console.log(`⏳ ${retryDelay/1000}秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        console.warn('⚠️ MongoDB连接测试最终失败:', error.message);
        return false;
      }
    }
  }
}

// ==================== 缓存管理 ====================

// 缓存键前缀
const CACHE_PREFIX = {
  PRODUCT: 'bike:product:',
  USER: 'bike:user:',
  ORDER: 'bike:order:',
  SESSION: 'bike:session:',
  STATS: 'bike:stats:'
};

// 缓存设置函数
async function setCache(key, value, ttl = 3600) {
  try {
    await redisClient.setEx(key, ttl, JSON.stringify(value));
  } catch (error) {
    console.warn('缓存设置失败:', error.message);
  }
}

// 缓存获取函数
async function getCache(key) {
  try {
    const cached = await redisClient.get(key);
    return cached ? JSON.parse(cached) : null;
  } catch (error) {
    console.warn('缓存获取失败:', error.message);
    return null;
  }
}

// 缓存删除函数
async function delCache(key) {
  try {
    await redisClient.del(key);
  } catch (error) {
    console.warn('缓存删除失败:', error.message);
  }
}

// ==================== 健康检查 ====================

async function healthCheck() {
  const postgresHealth = await testPostgresConnection(1, 1000);
  const redisHealth = await testRedisConnection(1, 1000);
  const mongoHealth = await testMongoConnection(1, 1000);
  
  return {
    status: postgresHealth && redisHealth && mongoHealth ? 'healthy' : 'degraded',
    services: {
      postgresql: postgresHealth ? 'connected' : 'disconnected',
      redis: redisHealth ? 'connected' : 'disconnected',
      mongodb: mongoHealth ? 'connected' : 'disconnected'
    },
    timestamp: new Date().toISOString()
  };
}

// ==================== 优雅关闭 ====================

async function gracefulShutdown() {
  console.log('🛑 正在关闭数据库连接...');
  
  try {
    // 关闭Redis连接
    if (redisClient && redisClient.isOpen) {
      await redisClient.quit();
      console.log('✅ Redis连接已关闭');
    }
    
    // 关闭PostgreSQL连接池
    if (postgresPool) {
      await postgresPool.end();
      console.log('✅ PostgreSQL连接池已关闭');
    }
    
    // 关闭MongoDB连接
    if (mongoClient) {
      await mongoClient.close();
      console.log('✅ MongoDB连接已关闭');
    }
    
  } catch (error) {
    console.error('❌ 关闭数据库连接时出错:', error);
  }
}

// ==================== 导出接口 ====================

export {
  // 数据库连接
  postgresPool,
  redisClient,
  mongoDb,
  
  // 连接测试
  testPostgresConnection,
  testRedisConnection,
  testMongoConnection,
  
  // 缓存管理
  CACHE_PREFIX,
  setCache,
  getCache,
  delCache,
  
  // 系统管理
  healthCheck,
  gracefulShutdown,
  connectMongoDB
};